{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "\n",
       "    <div class=\"bk-root\">\n",
       "        <a href=\"https://bokeh.pydata.org\" target=\"_blank\" class=\"bk-logo bk-logo-small bk-logo-notebook\"></a>\n",
       "        <span id=\"af93082c-260e-4605-8ddc-e924bc63d628\">Loading BokehJS ...</span>\n",
       "    </div>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "application/javascript": [
       "\n",
       "(function(root) {\n",
       "  function now() {\n",
       "    return new Date();\n",
       "  }\n",
       "\n",
       "  var force = true;\n",
       "\n",
       "  if (typeof (root._bokeh_onload_callbacks) === \"undefined\" || force === true) {\n",
       "    root._bokeh_onload_callbacks = [];\n",
       "    root._bokeh_is_loading = undefined;\n",
       "  }\n",
       "\n",
       "  var JS_MIME_TYPE = 'application/javascript';\n",
       "  var HTML_MIME_TYPE = 'text/html';\n",
       "  var EXEC_MIME_TYPE = 'application/vnd.bokehjs_exec.v0+json';\n",
       "  var CLASS_NAME = 'output_bokeh rendered_html';\n",
       "\n",
       "  /**\n",
       "   * Render data to the DOM node\n",
       "   */\n",
       "  function render(props, node) {\n",
       "    var script = document.createElement(\"script\");\n",
       "    node.appendChild(script);\n",
       "  }\n",
       "\n",
       "  /**\n",
       "   * Handle when an output is cleared or removed\n",
       "   */\n",
       "  function handleClearOutput(event, handle) {\n",
       "    var cell = handle.cell;\n",
       "\n",
       "    var id = cell.output_area._bokeh_element_id;\n",
       "    var server_id = cell.output_area._bokeh_server_id;\n",
       "    // Clean up Bokeh references\n",
       "    if (id != null && id in Bokeh.index) {\n",
       "      Bokeh.index[id].model.document.clear();\n",
       "      delete Bokeh.index[id];\n",
       "    }\n",
       "\n",
       "    if (server_id !== undefined) {\n",
       "      // Clean up Bokeh references\n",
       "      var cmd = \"from bokeh.io.state import curstate; print(curstate().uuid_to_server['\" + server_id + \"'].get_sessions()[0].document.roots[0]._id)\";\n",
       "      cell.notebook.kernel.execute(cmd, {\n",
       "        iopub: {\n",
       "          output: function(msg) {\n",
       "            var id = msg.content.text.trim();\n",
       "            if (id in Bokeh.index) {\n",
       "              Bokeh.index[id].model.document.clear();\n",
       "              delete Bokeh.index[id];\n",
       "            }\n",
       "          }\n",
       "        }\n",
       "      });\n",
       "      // Destroy server and session\n",
       "      var cmd = \"import bokeh.io.notebook as ion; ion.destroy_server('\" + server_id + \"')\";\n",
       "      cell.notebook.kernel.execute(cmd);\n",
       "    }\n",
       "  }\n",
       "\n",
       "  /**\n",
       "   * Handle when a new output is added\n",
       "   */\n",
       "  function handleAddOutput(event, handle) {\n",
       "    var output_area = handle.output_area;\n",
       "    var output = handle.output;\n",
       "\n",
       "    // limit handleAddOutput to display_data with EXEC_MIME_TYPE content only\n",
       "    if ((output.output_type != \"display_data\") || (!output.data.hasOwnProperty(EXEC_MIME_TYPE))) {\n",
       "      return\n",
       "    }\n",
       "\n",
       "    var toinsert = output_area.element.find(\".\" + CLASS_NAME.split(' ')[0]);\n",
       "\n",
       "    if (output.metadata[EXEC_MIME_TYPE][\"id\"] !== undefined) {\n",
       "      toinsert[toinsert.length - 1].firstChild.textContent = output.data[JS_MIME_TYPE];\n",
       "      // store reference to embed id on output_area\n",
       "      output_area._bokeh_element_id = output.metadata[EXEC_MIME_TYPE][\"id\"];\n",
       "    }\n",
       "    if (output.metadata[EXEC_MIME_TYPE][\"server_id\"] !== undefined) {\n",
       "      var bk_div = document.createElement(\"div\");\n",
       "      bk_div.innerHTML = output.data[HTML_MIME_TYPE];\n",
       "      var script_attrs = bk_div.children[0].attributes;\n",
       "      for (var i = 0; i < script_attrs.length; i++) {\n",
       "        toinsert[toinsert.length - 1].firstChild.setAttribute(script_attrs[i].name, script_attrs[i].value);\n",
       "      }\n",
       "      // store reference to server id on output_area\n",
       "      output_area._bokeh_server_id = output.metadata[EXEC_MIME_TYPE][\"server_id\"];\n",
       "    }\n",
       "  }\n",
       "\n",
       "  function register_renderer(events, OutputArea) {\n",
       "\n",
       "    function append_mime(data, metadata, element) {\n",
       "      // create a DOM node to render to\n",
       "      var toinsert = this.create_output_subarea(\n",
       "        metadata,\n",
       "        CLASS_NAME,\n",
       "        EXEC_MIME_TYPE\n",
       "      );\n",
       "      this.keyboard_manager.register_events(toinsert);\n",
       "      // Render to node\n",
       "      var props = {data: data, metadata: metadata[EXEC_MIME_TYPE]};\n",
       "      render(props, toinsert[toinsert.length - 1]);\n",
       "      element.append(toinsert);\n",
       "      return toinsert\n",
       "    }\n",
       "\n",
       "    /* Handle when an output is cleared or removed */\n",
       "    events.on('clear_output.CodeCell', handleClearOutput);\n",
       "    events.on('delete.Cell', handleClearOutput);\n",
       "\n",
       "    /* Handle when a new output is added */\n",
       "    events.on('output_added.OutputArea', handleAddOutput);\n",
       "\n",
       "    /**\n",
       "     * Register the mime type and append_mime function with output_area\n",
       "     */\n",
       "    OutputArea.prototype.register_mime_type(EXEC_MIME_TYPE, append_mime, {\n",
       "      /* Is output safe? */\n",
       "      safe: true,\n",
       "      /* Index of renderer in `output_area.display_order` */\n",
       "      index: 0\n",
       "    });\n",
       "  }\n",
       "\n",
       "  // register the mime type if in Jupyter Notebook environment and previously unregistered\n",
       "  if (root.Jupyter !== undefined) {\n",
       "    var events = require('base/js/events');\n",
       "    var OutputArea = require('notebook/js/outputarea').OutputArea;\n",
       "\n",
       "    if (OutputArea.prototype.mime_types().indexOf(EXEC_MIME_TYPE) == -1) {\n",
       "      register_renderer(events, OutputArea);\n",
       "    }\n",
       "  }\n",
       "\n",
       "  \n",
       "  if (typeof (root._bokeh_timeout) === \"undefined\" || force === true) {\n",
       "    root._bokeh_timeout = Date.now() + 5000;\n",
       "    root._bokeh_failed_load = false;\n",
       "  }\n",
       "\n",
       "  var NB_LOAD_WARNING = {'data': {'text/html':\n",
       "     \"<div style='background-color: #fdd'>\\n\"+\n",
       "     \"<p>\\n\"+\n",
       "     \"BokehJS does not appear to have successfully loaded. If loading BokehJS from CDN, this \\n\"+\n",
       "     \"may be due to a slow or bad network connection. Possible fixes:\\n\"+\n",
       "     \"</p>\\n\"+\n",
       "     \"<ul>\\n\"+\n",
       "     \"<li>re-rerun `output_notebook()` to attempt to load from CDN again, or</li>\\n\"+\n",
       "     \"<li>use INLINE resources instead, as so:</li>\\n\"+\n",
       "     \"</ul>\\n\"+\n",
       "     \"<code>\\n\"+\n",
       "     \"from bokeh.resources import INLINE\\n\"+\n",
       "     \"output_notebook(resources=INLINE)\\n\"+\n",
       "     \"</code>\\n\"+\n",
       "     \"</div>\"}};\n",
       "\n",
       "  function display_loaded() {\n",
       "    var el = document.getElementById(\"af93082c-260e-4605-8ddc-e924bc63d628\");\n",
       "    if (el != null) {\n",
       "      el.textContent = \"BokehJS is loading...\";\n",
       "    }\n",
       "    if (root.Bokeh !== undefined) {\n",
       "      if (el != null) {\n",
       "        el.textContent = \"BokehJS \" + root.Bokeh.version + \" successfully loaded.\";\n",
       "      }\n",
       "    } else if (Date.now() < root._bokeh_timeout) {\n",
       "      setTimeout(display_loaded, 100)\n",
       "    }\n",
       "  }\n",
       "\n",
       "\n",
       "  function run_callbacks() {\n",
       "    try {\n",
       "      root._bokeh_onload_callbacks.forEach(function(callback) { callback() });\n",
       "    }\n",
       "    finally {\n",
       "      delete root._bokeh_onload_callbacks\n",
       "    }\n",
       "    console.info(\"Bokeh: all callbacks have finished\");\n",
       "  }\n",
       "\n",
       "  function load_libs(js_urls, callback) {\n",
       "    root._bokeh_onload_callbacks.push(callback);\n",
       "    if (root._bokeh_is_loading > 0) {\n",
       "      console.log(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n",
       "      return null;\n",
       "    }\n",
       "    if (js_urls == null || js_urls.length === 0) {\n",
       "      run_callbacks();\n",
       "      return null;\n",
       "    }\n",
       "    console.log(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n",
       "    root._bokeh_is_loading = js_urls.length;\n",
       "    for (var i = 0; i < js_urls.length; i++) {\n",
       "      var url = js_urls[i];\n",
       "      var s = document.createElement('script');\n",
       "      s.src = url;\n",
       "      s.async = false;\n",
       "      s.onreadystatechange = s.onload = function() {\n",
       "        root._bokeh_is_loading--;\n",
       "        if (root._bokeh_is_loading === 0) {\n",
       "          console.log(\"Bokeh: all BokehJS libraries loaded\");\n",
       "          run_callbacks()\n",
       "        }\n",
       "      };\n",
       "      s.onerror = function() {\n",
       "        console.warn(\"failed to load library \" + url);\n",
       "      };\n",
       "      console.log(\"Bokeh: injecting script tag for BokehJS library: \", url);\n",
       "      document.getElementsByTagName(\"head\")[0].appendChild(s);\n",
       "    }\n",
       "  };var element = document.getElementById(\"af93082c-260e-4605-8ddc-e924bc63d628\");\n",
       "  if (element == null) {\n",
       "    console.log(\"Bokeh: ERROR: autoload.js configured with elementid 'af93082c-260e-4605-8ddc-e924bc63d628' but no matching script tag was found. \")\n",
       "    return false;\n",
       "  }\n",
       "\n",
       "  var js_urls = [\"https://cdn.pydata.org/bokeh/release/bokeh-0.13.0.min.js\", \"https://cdn.pydata.org/bokeh/release/bokeh-widgets-0.13.0.min.js\", \"https://cdn.pydata.org/bokeh/release/bokeh-tables-0.13.0.min.js\", \"https://cdn.pydata.org/bokeh/release/bokeh-gl-0.13.0.min.js\"];\n",
       "\n",
       "  var inline_js = [\n",
       "    function(Bokeh) {\n",
       "      Bokeh.set_log_level(\"info\");\n",
       "    },\n",
       "    \n",
       "    function(Bokeh) {\n",
       "      \n",
       "    },\n",
       "    function(Bokeh) {\n",
       "      console.log(\"Bokeh: injecting CSS: https://cdn.pydata.org/bokeh/release/bokeh-0.13.0.min.css\");\n",
       "      Bokeh.embed.inject_css(\"https://cdn.pydata.org/bokeh/release/bokeh-0.13.0.min.css\");\n",
       "      console.log(\"Bokeh: injecting CSS: https://cdn.pydata.org/bokeh/release/bokeh-widgets-0.13.0.min.css\");\n",
       "      Bokeh.embed.inject_css(\"https://cdn.pydata.org/bokeh/release/bokeh-widgets-0.13.0.min.css\");\n",
       "      console.log(\"Bokeh: injecting CSS: https://cdn.pydata.org/bokeh/release/bokeh-tables-0.13.0.min.css\");\n",
       "      Bokeh.embed.inject_css(\"https://cdn.pydata.org/bokeh/release/bokeh-tables-0.13.0.min.css\");\n",
       "    }\n",
       "  ];\n",
       "\n",
       "  function run_inline_js() {\n",
       "    \n",
       "    if ((root.Bokeh !== undefined) || (force === true)) {\n",
       "      for (var i = 0; i < inline_js.length; i++) {\n",
       "        inline_js[i].call(root, root.Bokeh);\n",
       "      }if (force === true) {\n",
       "        display_loaded();\n",
       "      }} else if (Date.now() < root._bokeh_timeout) {\n",
       "      setTimeout(run_inline_js, 100);\n",
       "    } else if (!root._bokeh_failed_load) {\n",
       "      console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n",
       "      root._bokeh_failed_load = true;\n",
       "    } else if (force !== true) {\n",
       "      var cell = $(document.getElementById(\"af93082c-260e-4605-8ddc-e924bc63d628\")).parents('.cell').data().cell;\n",
       "      cell.output_area.append_execute_result(NB_LOAD_WARNING)\n",
       "    }\n",
       "\n",
       "  }\n",
       "\n",
       "  if (root._bokeh_is_loading === 0) {\n",
       "    console.log(\"Bokeh: BokehJS loaded, going straight to plotting\");\n",
       "    run_inline_js();\n",
       "  } else {\n",
       "    load_libs(js_urls, function() {\n",
       "      console.log(\"Bokeh: BokehJS plotting callback run at\", now());\n",
       "      run_inline_js();\n",
       "    });\n",
       "  }\n",
       "}(window));"
      ],
      "application/vnd.bokehjs_load.v0+json": "\n(function(root) {\n  function now() {\n    return new Date();\n  }\n\n  var force = true;\n\n  if (typeof (root._bokeh_onload_callbacks) === \"undefined\" || force === true) {\n    root._bokeh_onload_callbacks = [];\n    root._bokeh_is_loading = undefined;\n  }\n\n  \n\n  \n  if (typeof (root._bokeh_timeout) === \"undefined\" || force === true) {\n    root._bokeh_timeout = Date.now() + 5000;\n    root._bokeh_failed_load = false;\n  }\n\n  var NB_LOAD_WARNING = {'data': {'text/html':\n     \"<div style='background-color: #fdd'>\\n\"+\n     \"<p>\\n\"+\n     \"BokehJS does not appear to have successfully loaded. If loading BokehJS from CDN, this \\n\"+\n     \"may be due to a slow or bad network connection. Possible fixes:\\n\"+\n     \"</p>\\n\"+\n     \"<ul>\\n\"+\n     \"<li>re-rerun `output_notebook()` to attempt to load from CDN again, or</li>\\n\"+\n     \"<li>use INLINE resources instead, as so:</li>\\n\"+\n     \"</ul>\\n\"+\n     \"<code>\\n\"+\n     \"from bokeh.resources import INLINE\\n\"+\n     \"output_notebook(resources=INLINE)\\n\"+\n     \"</code>\\n\"+\n     \"</div>\"}};\n\n  function display_loaded() {\n    var el = document.getElementById(\"af93082c-260e-4605-8ddc-e924bc63d628\");\n    if (el != null) {\n      el.textContent = \"BokehJS is loading...\";\n    }\n    if (root.Bokeh !== undefined) {\n      if (el != null) {\n        el.textContent = \"BokehJS \" + root.Bokeh.version + \" successfully loaded.\";\n      }\n    } else if (Date.now() < root._bokeh_timeout) {\n      setTimeout(display_loaded, 100)\n    }\n  }\n\n\n  function run_callbacks() {\n    try {\n      root._bokeh_onload_callbacks.forEach(function(callback) { callback() });\n    }\n    finally {\n      delete root._bokeh_onload_callbacks\n    }\n    console.info(\"Bokeh: all callbacks have finished\");\n  }\n\n  function load_libs(js_urls, callback) {\n    root._bokeh_onload_callbacks.push(callback);\n    if (root._bokeh_is_loading > 0) {\n      console.log(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n      return null;\n    }\n    if (js_urls == null || js_urls.length === 0) {\n      run_callbacks();\n      return null;\n    }\n    console.log(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n    root._bokeh_is_loading = js_urls.length;\n    for (var i = 0; i < js_urls.length; i++) {\n      var url = js_urls[i];\n      var s = document.createElement('script');\n      s.src = url;\n      s.async = false;\n      s.onreadystatechange = s.onload = function() {\n        root._bokeh_is_loading--;\n        if (root._bokeh_is_loading === 0) {\n          console.log(\"Bokeh: all BokehJS libraries loaded\");\n          run_callbacks()\n        }\n      };\n      s.onerror = function() {\n        console.warn(\"failed to load library \" + url);\n      };\n      console.log(\"Bokeh: injecting script tag for BokehJS library: \", url);\n      document.getElementsByTagName(\"head\")[0].appendChild(s);\n    }\n  };var element = document.getElementById(\"af93082c-260e-4605-8ddc-e924bc63d628\");\n  if (element == null) {\n    console.log(\"Bokeh: ERROR: autoload.js configured with elementid 'af93082c-260e-4605-8ddc-e924bc63d628' but no matching script tag was found. \")\n    return false;\n  }\n\n  var js_urls = [\"https://cdn.pydata.org/bokeh/release/bokeh-0.13.0.min.js\", \"https://cdn.pydata.org/bokeh/release/bokeh-widgets-0.13.0.min.js\", \"https://cdn.pydata.org/bokeh/release/bokeh-tables-0.13.0.min.js\", \"https://cdn.pydata.org/bokeh/release/bokeh-gl-0.13.0.min.js\"];\n\n  var inline_js = [\n    function(Bokeh) {\n      Bokeh.set_log_level(\"info\");\n    },\n    \n    function(Bokeh) {\n      \n    },\n    function(Bokeh) {\n      console.log(\"Bokeh: injecting CSS: https://cdn.pydata.org/bokeh/release/bokeh-0.13.0.min.css\");\n      Bokeh.embed.inject_css(\"https://cdn.pydata.org/bokeh/release/bokeh-0.13.0.min.css\");\n      console.log(\"Bokeh: injecting CSS: https://cdn.pydata.org/bokeh/release/bokeh-widgets-0.13.0.min.css\");\n      Bokeh.embed.inject_css(\"https://cdn.pydata.org/bokeh/release/bokeh-widgets-0.13.0.min.css\");\n      console.log(\"Bokeh: injecting CSS: https://cdn.pydata.org/bokeh/release/bokeh-tables-0.13.0.min.css\");\n      Bokeh.embed.inject_css(\"https://cdn.pydata.org/bokeh/release/bokeh-tables-0.13.0.min.css\");\n    }\n  ];\n\n  function run_inline_js() {\n    \n    if ((root.Bokeh !== undefined) || (force === true)) {\n      for (var i = 0; i < inline_js.length; i++) {\n        inline_js[i].call(root, root.Bokeh);\n      }if (force === true) {\n        display_loaded();\n      }} else if (Date.now() < root._bokeh_timeout) {\n      setTimeout(run_inline_js, 100);\n    } else if (!root._bokeh_failed_load) {\n      console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n      root._bokeh_failed_load = true;\n    } else if (force !== true) {\n      var cell = $(document.getElementById(\"af93082c-260e-4605-8ddc-e924bc63d628\")).parents('.cell').data().cell;\n      cell.output_area.append_execute_result(NB_LOAD_WARNING)\n    }\n\n  }\n\n  if (root._bokeh_is_loading === 0) {\n    console.log(\"Bokeh: BokehJS loaded, going straight to plotting\");\n    run_inline_js();\n  } else {\n    load_libs(js_urls, function() {\n      console.log(\"Bokeh: BokehJS plotting callback run at\", now());\n      run_inline_js();\n    });\n  }\n}(window));"
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "import numpy as np\n",
    "from scipy.stats import norm\n",
    "import matplotlib.pylab as plt\n",
    "import pandas as pd\n",
    "from bokeh.layouts import row, widgetbox, layout, gridplot\n",
    "from bokeh.models import CustomJS, Slider\n",
    "from bokeh.plotting import figure, output_file, show, ColumnDataSource\n",
    "from bokeh.models.glyphs import MultiLine\n",
    "from bokeh.io import output_notebook\n",
    "from bokeh.models.widgets import Div\n",
    "%matplotlib inline\n",
    "output_notebook()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Create Fake Data\n",
    "Let's start by generating a wee fake dataset."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 44,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "num_data = 5\n",
    "X = norm.rvs(size=(num_data,2), random_state=4)*2\n",
    "X = np.dot(X, np.linalg.cholesky([[1, 0.8], [0.8, 0.8]]))\n",
    "m = X.mean(axis=0)\n",
    "X = X - m"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Let's take a look at the data we generated."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 45,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[ 1.87346497,  0.55034968],\n",
       "       [ 0.09035918,  0.70526742],\n",
       "       [-2.39950719, -1.11727317],\n",
       "       [ 0.63472617,  0.62924876],\n",
       "       [-0.19904312, -0.76759269]])"
      ]
     },
     "execution_count": 45,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "X"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 46,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<matplotlib.collections.PathCollection at 0x11125fa90>"
      ]
     },
     "execution_count": 46,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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\nrkJggg==\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.scatter(X[:, 0],X[:, 1])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## An Interactive Plot\n",
    "Now we'll create an interactive plot with these data."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 52,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "\n",
       "\n",
       "\n",
       "\n",
       "\n",
       "\n",
       "  <div class=\"bk-root\" id=\"3f0d4388-a153-4321-8137-0e704d4f663f\"></div>\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "application/javascript": [
       "(function(root) {\n",
       "  function embed_document(root) {\n",
       "    \n",
       "  var docs_json = {\"9688e211-cf17-4914-8972-030fd03f0983\":{\"roots\":{\"references\":[{\"attributes\":{\"source\":{\"id\":\"e0f16080-ad75-40e4-8ce0-5c8b830430ae\",\"type\":\"ColumnDataSource\"}},\"id\":\"96d3019d-d9df-4c46-9859-6f12d2f3c1d8\",\"type\":\"CDSView\"},{\"attributes\":{\"data_source\":{\"id\":\"e0f16080-ad75-40e4-8ce0-5c8b830430ae\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"b29a0782-09b8-4d63-ab2c-bb32958ec3a1\",\"type\":\"MultiLine\"},\"hover_glyph\":null,\"muted_glyph\":null,\"view\":{\"id\":\"ce07145e-e9a7-40b8-aeea-d26157bd4a57\",\"type\":\"CDSView\"}},\"id\":\"ceaaa24d-cfa4-4bed-a784-5bcf20cb55d7\",\"type\":\"GlyphRenderer\"},{\"attributes\":{},\"id\":\"b831910b-e9aa-4346-9fc1-d6d6d173b0f5\",\"type\":\"BasicTickFormatter\"},{\"attributes\":{\"line_alpha\":0.5,\"x\":{\"field\":\"z0\"},\"y\":{\"field\":\"z1\"}},\"id\":\"ce7751ec-6bb8-4059-9fa5-f3603f662d91\",\"type\":\"Line\"},{\"attributes\":{\"line_alpha\":0.1,\"line_color\":\"#1f77b4\",\"x\":{\"field\":\"z0\"},\"y\":{\"field\":\"z1\"}},\"id\":\"ffbc96c3-c921-4fec-b156-59590a97eb61\",\"type\":\"Line\"},{\"attributes\":{\"data_source\":{\"id\":\"e0f16080-ad75-40e4-8ce0-5c8b830430ae\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"ce7751ec-6bb8-4059-9fa5-f3603f662d91\",\"type\":\"Line\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"ffbc96c3-c921-4fec-b156-59590a97eb61\",\"type\":\"Line\"},\"selection_glyph\":null,\"view\":{\"id\":\"371496f4-6401-494a-8e1e-8922f98a8381\",\"type\":\"CDSView\"}},\"id\":\"732f3eca-9aa0-49dd-a915-37c542ed0b13\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"source\":{\"id\":\"e0f16080-ad75-40e4-8ce0-5c8b830430ae\",\"type\":\"ColumnDataSource\"}},\"id\":\"371496f4-6401-494a-8e1e-8922f98a8381\",\"type\":\"CDSView\"},{\"attributes\":{\"line_color\":{\"value\":\"#8073ac\"},\"xs\":{\"field\":\"x0s\"},\"ys\":{\"field\":\"x1s\"}},\"id\":\"b29a0782-09b8-4d63-ab2c-bb32958ec3a1\",\"type\":\"MultiLine\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.6},\"fill_color\":{\"value\":\"firebrick\"},\"line_alpha\":{\"value\":0.6},\"line_color\":{\"value\":\"firebrick\"},\"x\":{\"field\":\"z0\"},\"y\":{\"field\":\"z1\"}},\"id\":\"f599ac0d-4836-41bf-b051-e3ce9e7fdbc1\",\"type\":\"Circle\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"x\":{\"field\":\"z0\"},\"y\":{\"field\":\"z1\"}},\"id\":\"8d50f232-f527-4d04-a016-2b617645e5e2\",\"type\":\"Circle\"},{\"attributes\":{\"data_source\":{\"id\":\"e0f16080-ad75-40e4-8ce0-5c8b830430ae\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"f599ac0d-4836-41bf-b051-e3ce9e7fdbc1\",\"type\":\"Circle\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"8d50f232-f527-4d04-a016-2b617645e5e2\",\"type\":\"Circle\"},\"selection_glyph\":null,\"view\":{\"id\":\"0b2f827f-567e-41a9-a262-a466a845fe93\",\"type\":\"CDSView\"}},\"id\":\"967adcea-438d-448c-8a31-19dc7994c7c5\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"source\":{\"id\":\"e0f16080-ad75-40e4-8ce0-5c8b830430ae\",\"type\":\"ColumnDataSource\"}},\"id\":\"0b2f827f-567e-41a9-a262-a466a845fe93\",\"type\":\"CDSView\"},{\"attributes\":{\"args\":{\"ang\":{\"id\":\"2e075f01-7f18-4d77-96f9-0b47c944e031\",\"type\":\"Slider\"},\"source\":{\"id\":\"e0f16080-ad75-40e4-8ce0-5c8b830430ae\",\"type\":\"ColumnDataSource\"}},\"code\":\"\\n    var data = source.data;\\n    var x0 = data['x0']\\n    var x1 = data['x1']\\n    \\n    var d = data['d']\\n    \\n    var z0 = data['z0']\\n    var z1 = data['z1']\\n    \\n    var x0s = data['x0s']\\n    var x1s = data['x1s']\\n    \\n    var A = ang.value*Math.PI/180;\\n\\n    var w = [Math.cos(A), Math.sin(A)];\\n\\n    for (var i = 0; i < x0.length; i++) {\\n        d[i] = x0[i]*w[0] + x1[i]*w[1];\\n        z0[i] = w[0]*d[i];\\n        z1[i] = w[1]*d[i];\\n        x0s[i] = [x0[i], z0[i]];\\n        x1s[i] = [x1[i], z1[i]];\\n    }\\n\\n    data['z0'] = z0\\n    data['z1'] = z1\\n    data['x0s'] = x0s\\n    data['x1s'] = x1s\\n    data['d'] = d\\n    \\n    source.change.emit();\\n\"},\"id\":\"440db900-bbb7-4b5c-a020-34ccf4adbc34\",\"type\":\"CustomJS\"},{\"attributes\":{\"height\":100,\"text\":\"Instructions: There's a lot of code in the cell above! What just happened? The blue dots are our original data points. We are choosing the direction of the first PC for this dataset; this direction is represented by the black line. The red dots are the projections of the data onto the new basis direction. Using the slider bar, change the angle of the new basis direction, and observe how the projections and the variance of the projections, represented by the spread of the points in the plot on the right, change.\",\"width\":900},\"id\":\"5265e643-f94c-4d61-946c-ef07e7708f40\",\"type\":\"Div\"},{\"attributes\":{\"source\":{\"id\":\"e0f16080-ad75-40e4-8ce0-5c8b830430ae\",\"type\":\"ColumnDataSource\"}},\"id\":\"ce07145e-e9a7-40b8-aeea-d26157bd4a57\",\"type\":\"CDSView\"},{\"attributes\":{\"height\":80,\"width\":200},\"id\":\"4a9b1f99-ff4e-4c3e-8927-686240ce3c08\",\"type\":\"Div\"},{\"attributes\":{\"callback\":{\"id\":\"440db900-bbb7-4b5c-a020-34ccf4adbc34\",\"type\":\"CustomJS\"},\"end\":360,\"start\":0,\"step\":0.1,\"title\":\"Angle\",\"value\":1},\"id\":\"2e075f01-7f18-4d77-96f9-0b47c944e031\",\"type\":\"Slider\"},{\"attributes\":{\"children\":[{\"id\":\"d23d327a-4028-4fff-9006-ae115b201b46\",\"type\":\"Column\"},{\"id\":\"0a4902e1-464e-4cb4-93d7-dc114398e3e7\",\"type\":\"Column\"}]},\"id\":\"669fb717-fb1b-4f27-93cd-b1f34b4ce6f3\",\"type\":\"Row\"},{\"attributes\":{\"children\":[{\"id\":\"4a9b1f99-ff4e-4c3e-8927-686240ce3c08\",\"type\":\"Div\"}]},\"id\":\"cc4fb52b-66c0-4e5c-b838-8620db44fddc\",\"type\":\"WidgetBox\"},{\"attributes\":{\"height\":95,\"width\":200},\"id\":\"39dbcc4c-2a5c-4875-a818-c5e6ae17d5e9\",\"type\":\"Div\"},{\"attributes\":{\"children\":[{\"id\":\"5265e643-f94c-4d61-946c-ef07e7708f40\",\"type\":\"Div\"}]},\"id\":\"b71cf2d2-65b6-44da-93e5-83ef49739937\",\"type\":\"WidgetBox\"},{\"attributes\":{\"children\":[{\"id\":\"2e075f01-7f18-4d77-96f9-0b47c944e031\",\"type\":\"Slider\"}]},\"id\":\"41f73368-647d-4cc1-b32e-56e29ea4c454\",\"type\":\"WidgetBox\"},{\"attributes\":{\"children\":[{\"id\":\"39dbcc4c-2a5c-4875-a818-c5e6ae17d5e9\",\"type\":\"Div\"}]},\"id\":\"0ba128b0-0995-41cd-a0e1-8bd00176e365\",\"type\":\"WidgetBox\"},{\"attributes\":{\"children\":[{\"id\":\"669fb717-fb1b-4f27-93cd-b1f34b4ce6f3\",\"type\":\"Row\"}]},\"id\":\"d7710cfe-79b6-4baa-9365-7cbf833dd3b2\",\"type\":\"Column\"},{\"attributes\":{\"below\":[{\"id\":\"a1c83182-3bc3-4381-858f-803c347cf7b4\",\"type\":\"LinearAxis\"}],\"left\":[{\"id\":\"e15a7ba8-7265-4570-9f0f-58e3c6094c63\",\"type\":\"LinearAxis\"}],\"plot_height\":300,\"plot_width\":300,\"renderers\":[{\"id\":\"a1c83182-3bc3-4381-858f-803c347cf7b4\",\"type\":\"LinearAxis\"},{\"id\":\"7a4f6dae-e4c8-40a6-a9b3-995274e6692f\",\"type\":\"Grid\"},{\"id\":\"e15a7ba8-7265-4570-9f0f-58e3c6094c63\",\"type\":\"LinearAxis\"},{\"id\":\"e05a4ef4-5e61-40fc-b4c8-473879607903\",\"type\":\"Grid\"},{\"id\":\"656edf3c-53f8-46a9-a1ea-a34a902b5d44\",\"type\":\"BoxAnnotation\"},{\"id\":\"5d377166-00b6-4192-847c-058f619d851d\",\"type\":\"GlyphRenderer\"}],\"title\":{\"id\":\"7aa5d612-daf9-4dd1-a784-d65f1756e6d2\",\"type\":\"Title\"},\"toolbar\":{\"id\":\"d44d884c-f167-4c6d-8efd-86ddf0aa4679\",\"type\":\"Toolbar\"},\"x_range\":{\"id\":\"1d121b47-410e-4328-89cb-0fd5174ad8c6\",\"type\":\"Range1d\"},\"x_scale\":{\"id\":\"1d3c5444-78aa-4f12-9126-2551c93f3629\",\"type\":\"LinearScale\"},\"y_range\":{\"id\":\"57f933c8-bba2-4a30-8fa8-31a94b6ea7f2\",\"type\":\"Range1d\"},\"y_scale\":{\"id\":\"6d63ed0f-81fd-43dc-a795-b7a5314a7777\",\"type\":\"LinearScale\"}},\"id\":\"50fe396b-f3aa-42c8-8200-f7f5cf0b903f\",\"subtype\":\"Figure\",\"type\":\"Plot\"},{\"attributes\":{\"children\":[{\"id\":\"b71cf2d2-65b6-44da-93e5-83ef49739937\",\"type\":\"WidgetBox\"},{\"id\":\"d42223cd-5dde-49a9-bbc8-509cab218ad5\",\"subtype\":\"Figure\",\"type\":\"Plot\"}]},\"id\":\"d23d327a-4028-4fff-9006-ae115b201b46\",\"type\":\"Column\"},{\"attributes\":{\"plot\":null,\"text\":\"\"},\"id\":\"70fbac90-95dd-419b-b4e5-6e60941450d1\",\"type\":\"Title\"},{\"attributes\":{\"below\":[{\"id\":\"b7b3be6c-6346-4b12-a756-b2f70af180fc\",\"type\":\"LinearAxis\"}],\"left\":[{\"id\":\"29fbd1ea-4200-4d42-b6eb-886deff01963\",\"type\":\"LinearAxis\"}],\"match_aspect\":true,\"renderers\":[{\"id\":\"b7b3be6c-6346-4b12-a756-b2f70af180fc\",\"type\":\"LinearAxis\"},{\"id\":\"16578882-4883-4993-a55e-d7f173c0f756\",\"type\":\"Grid\"},{\"id\":\"29fbd1ea-4200-4d42-b6eb-886deff01963\",\"type\":\"LinearAxis\"},{\"id\":\"92b7a05b-2be2-4a18-b51b-4448b262417d\",\"type\":\"Grid\"},{\"id\":\"698caba9-9528-4aac-a9b3-9a7a56650086\",\"type\":\"BoxAnnotation\"},{\"id\":\"33e9372b-dae7-4b04-8469-3158cda33b36\",\"type\":\"GlyphRenderer\"},{\"id\":\"732f3eca-9aa0-49dd-a915-37c542ed0b13\",\"type\":\"GlyphRenderer\"},{\"id\":\"967adcea-438d-448c-8a31-19dc7994c7c5\",\"type\":\"GlyphRenderer\"},{\"id\":\"ceaaa24d-cfa4-4bed-a784-5bcf20cb55d7\",\"type\":\"GlyphRenderer\"}],\"title\":{\"id\":\"70fbac90-95dd-419b-b4e5-6e60941450d1\",\"type\":\"Title\"},\"toolbar\":{\"id\":\"61a8cf4d-39e4-4c1c-bdff-c5c23adbdb73\",\"type\":\"Toolbar\"},\"x_range\":{\"id\":\"35cd6359-02b1-412d-83f9-f4691b1cd0e1\",\"type\":\"Range1d\"},\"x_scale\":{\"id\":\"acbceab1-7923-49c9-a674-beca0ab3b835\",\"type\":\"LinearScale\"},\"y_range\":{\"id\":\"38e087c7-c18c-402d-8b19-a56f638979c5\",\"type\":\"Range1d\"},\"y_scale\":{\"id\":\"4486856c-1021-40f6-9a14-d942abd1f640\",\"type\":\"LinearScale\"}},\"id\":\"d42223cd-5dde-49a9-bbc8-509cab218ad5\",\"subtype\":\"Figure\",\"type\":\"Plot\"},{\"attributes\":{\"children\":[{\"id\":\"cc4fb52b-66c0-4e5c-b838-8620db44fddc\",\"type\":\"WidgetBox\"},{\"id\":\"41f73368-647d-4cc1-b32e-56e29ea4c454\",\"type\":\"WidgetBox\"},{\"id\":\"0ba128b0-0995-41cd-a0e1-8bd00176e365\",\"type\":\"WidgetBox\"},{\"id\":\"50fe396b-f3aa-42c8-8200-f7f5cf0b903f\",\"subtype\":\"Figure\",\"type\":\"Plot\"}]},\"id\":\"0a4902e1-464e-4cb4-93d7-dc114398e3e7\",\"type\":\"Column\"},{\"attributes\":{\"callback\":null,\"data\":{\"d\":{\"__ndarray__\":\"AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fw==\",\"dtype\":\"float64\",\"shape\":[5]},\"dzs\":{\"__ndarray__\":\"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==\",\"dtype\":\"float64\",\"shape\":[5]},\"x0\":{\"__ndarray__\":\"/o75Z7b5/T8Y67BmxyG3P8qvodMwMgPAOtjbQK1P5D/EUXm8PnrJvw==\",\"dtype\":\"float64\",\"shape\":[5]},\"x0s\":[{\"__ndarray__\":\"AAAAAAAA+H8AAAAAAAD4fw==\",\"dtype\":\"float64\",\"shape\":[2]},{\"__ndarray__\":\"AAAAAAAA+H8AAAAAAAD4fw==\",\"dtype\":\"float64\",\"shape\":[2]},{\"__ndarray__\":\"AAAAAAAA+H8AAAAAAAD4fw==\",\"dtype\":\"float64\",\"shape\":[2]},{\"__ndarray__\":\"AAAAAAAA+H8AAAAAAAD4fw==\",\"dtype\":\"float64\",\"shape\":[2]},{\"__ndarray__\":\"AAAAAAAA+H8AAAAAAAD4fw==\",\"dtype\":\"float64\",\"shape\":[2]}],\"x1\":{\"__ndarray__\":\"CSw78Hac4T9f5pz8jJHmP/wDUdVZ4PG/ivpISc4i5D/6BH+LHpDovw==\",\"dtype\":\"float64\",\"shape\":[5]},\"x1s\":[{\"__ndarray__\":\"AAAAAAAA+H8AAAAAAAD4fw==\",\"dtype\":\"float64\",\"shape\":[2]},{\"__ndarray__\":\"AAAAAAAA+H8AAAAAAAD4fw==\",\"dtype\":\"float64\",\"shape\":[2]},{\"__ndarray__\":\"AAAAAAAA+H8AAAAAAAD4fw==\",\"dtype\":\"float64\",\"shape\":[2]},{\"__ndarray__\":\"AAAAAAAA+H8AAAAAAAD4fw==\",\"dtype\":\"float64\",\"shape\":[2]},{\"__ndarray__\":\"AAAAAAAA+H8AAAAAAAD4fw==\",\"dtype\":\"float64\",\"shape\":[2]}],\"z0\":{\"__ndarray__\":\"AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fw==\",\"dtype\":\"float64\",\"shape\":[5]},\"z1\":{\"__ndarray__\":\"AAAAAAAA+H8AAAAAAAD4fwAAAAAAAPh/AAAAAAAA+H8AAAAAAAD4fw==\",\"dtype\":\"float64\",\"shape\":[5]}},\"selected\":{\"id\":\"80684a73-d243-4e5d-bb51-e6c7fdf69819\",\"type\":\"Selection\"},\"selection_policy\":{\"id\":\"4c237a65-061e-4313-b977-4521de04f8da\",\"type\":\"UnionRenderers\"}},\"id\":\"e0f16080-ad75-40e4-8ce0-5c8b830430ae\",\"type\":\"ColumnDataSource\"},{\"attributes\":{},\"id\":\"8d0b6f61-71a4-44a8-ae46-33436c7e7c2b\",\"type\":\"BasicTickFormatter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"x\":{\"field\":\"d\"},\"y\":{\"field\":\"dzs\"}},\"id\":\"5353bb36-e344-4b2e-9bfb-e2213dec7fcb\",\"type\":\"Circle\"},{\"attributes\":{\"active_drag\":\"auto\",\"active_inspect\":\"auto\",\"active_multi\":null,\"active_scroll\":\"auto\",\"active_tap\":\"auto\",\"tools\":[{\"id\":\"296697bf-af72-4cdf-96b4-56a2a898e988\",\"type\":\"PanTool\"},{\"id\":\"5120e79d-2c86-453b-87d6-27a661844017\",\"type\":\"WheelZoomTool\"},{\"id\":\"4cdff682-43af-4b79-acac-b0b0328048f3\",\"type\":\"BoxZoomTool\"},{\"id\":\"c7312140-9e29-46f9-85d0-9fe36461527e\",\"type\":\"SaveTool\"},{\"id\":\"0839ab92-6831-41e8-8bd3-5b56fa308c17\",\"type\":\"ResetTool\"},{\"id\":\"e9c4e391-6224-43ad-9240-6118eda859c4\",\"type\":\"HelpTool\"}]},\"id\":\"61a8cf4d-39e4-4c1c-bdff-c5c23adbdb73\",\"type\":\"Toolbar\"},{\"attributes\":{},\"id\":\"80684a73-d243-4e5d-bb51-e6c7fdf69819\",\"type\":\"Selection\"},{\"attributes\":{\"callback\":null,\"end\":2.5,\"start\":-3},\"id\":\"35cd6359-02b1-412d-83f9-f4691b1cd0e1\",\"type\":\"Range1d\"},{\"attributes\":{},\"id\":\"5d053908-faea-4f5b-bdb2-d325361e3c30\",\"type\":\"BasicTickFormatter\"},{\"attributes\":{\"plot\":{\"id\":\"d42223cd-5dde-49a9-bbc8-509cab218ad5\",\"subtype\":\"Figure\",\"type\":\"Plot\"},\"ticker\":{\"id\":\"de859a6c-bc99-4d79-8662-0df875bf8c74\",\"type\":\"BasicTicker\"}},\"id\":\"16578882-4883-4993-a55e-d7f173c0f756\",\"type\":\"Grid\"},{\"attributes\":{},\"id\":\"4c237a65-061e-4313-b977-4521de04f8da\",\"type\":\"UnionRenderers\"},{\"attributes\":{\"callback\":null,\"end\":2.5,\"start\":-2.5},\"id\":\"38e087c7-c18c-402d-8b19-a56f638979c5\",\"type\":\"Range1d\"},{\"attributes\":{},\"id\":\"acbceab1-7923-49c9-a674-beca0ab3b835\",\"type\":\"LinearScale\"},{\"attributes\":{\"active_drag\":\"auto\",\"active_inspect\":\"auto\",\"active_multi\":null,\"active_scroll\":\"auto\",\"active_tap\":\"auto\",\"tools\":[{\"id\":\"ffc8c8cc-9107-462d-961c-54e149803f67\",\"type\":\"PanTool\"},{\"id\":\"e0e32655-b3e4-4d32-b267-b7e6b36aabef\",\"type\":\"WheelZoomTool\"},{\"id\":\"c44f5c85-f558-4e31-9b61-55575409a220\",\"type\":\"BoxZoomTool\"},{\"id\":\"4cf46e1c-71c4-450f-88b6-f7aa882c2fc2\",\"type\":\"SaveTool\"},{\"id\":\"e46c7abb-d891-40e2-a6f4-2bcd1992177f\",\"type\":\"ResetTool\"},{\"id\":\"9425dd91-7c71-43ed-8573-d60ff4963916\",\"type\":\"HelpTool\"}]},\"id\":\"d44d884c-f167-4c6d-8efd-86ddf0aa4679\",\"type\":\"Toolbar\"},{\"attributes\":{\"formatter\":{\"id\":\"8d0b6f61-71a4-44a8-ae46-33436c7e7c2b\",\"type\":\"BasicTickFormatter\"},\"plot\":{\"id\":\"d42223cd-5dde-49a9-bbc8-509cab218ad5\",\"subtype\":\"Figure\",\"type\":\"Plot\"},\"ticker\":{\"id\":\"de859a6c-bc99-4d79-8662-0df875bf8c74\",\"type\":\"BasicTicker\"}},\"id\":\"b7b3be6c-6346-4b12-a756-b2f70af180fc\",\"type\":\"LinearAxis\"},{\"attributes\":{},\"id\":\"de859a6c-bc99-4d79-8662-0df875bf8c74\",\"type\":\"BasicTicker\"},{\"attributes\":{\"formatter\":{\"id\":\"23a99c4b-852c-4bf2-ac61-864e563ff37c\",\"type\":\"BasicTickFormatter\"},\"plot\":{\"id\":\"d42223cd-5dde-49a9-bbc8-509cab218ad5\",\"subtype\":\"Figure\",\"type\":\"Plot\"},\"ticker\":{\"id\":\"cba9f156-f2ab-4f8b-980d-d1eb25037f23\",\"type\":\"BasicTicker\"}},\"id\":\"29fbd1ea-4200-4d42-b6eb-886deff01963\",\"type\":\"LinearAxis\"},{\"attributes\":{},\"id\":\"cba9f156-f2ab-4f8b-980d-d1eb25037f23\",\"type\":\"BasicTicker\"},{\"attributes\":{\"dimension\":1,\"plot\":{\"id\":\"d42223cd-5dde-49a9-bbc8-509cab218ad5\",\"subtype\":\"Figure\",\"type\":\"Plot\"},\"ticker\":{\"id\":\"cba9f156-f2ab-4f8b-980d-d1eb25037f23\",\"type\":\"BasicTicker\"}},\"id\":\"92b7a05b-2be2-4a18-b51b-4448b262417d\",\"type\":\"Grid\"},{\"attributes\":{\"callback\":null,\"end\":3,\"start\":-3},\"id\":\"1d121b47-410e-4328-89cb-0fd5174ad8c6\",\"type\":\"Range1d\"},{\"attributes\":{\"source\":{\"id\":\"e0f16080-ad75-40e4-8ce0-5c8b830430ae\",\"type\":\"ColumnDataSource\"}},\"id\":\"ef855f12-300c-4e04-8d72-9f119a3378e4\",\"type\":\"CDSView\"},{\"attributes\":{\"data_source\":{\"id\":\"e0f16080-ad75-40e4-8ce0-5c8b830430ae\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"47d1c3fb-8cfa-49be-acb9-c9cf904f7cab\",\"type\":\"Circle\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"d676ac57-1d3f-448f-ba02-38042005d92d\",\"type\":\"Circle\"},\"selection_glyph\":null,\"view\":{\"id\":\"96d3019d-d9df-4c46-9859-6f12d2f3c1d8\",\"type\":\"CDSView\"}},\"id\":\"33e9372b-dae7-4b04-8469-3158cda33b36\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"bottom_units\":\"screen\",\"fill_alpha\":{\"value\":0.5},\"fill_color\":{\"value\":\"lightgrey\"},\"left_units\":\"screen\",\"level\":\"overlay\",\"line_alpha\":{\"value\":1.0},\"line_color\":{\"value\":\"black\"},\"line_dash\":[4,4],\"line_width\":{\"value\":2},\"plot\":null,\"render_mode\":\"css\",\"right_units\":\"screen\",\"top_units\":\"screen\"},\"id\":\"698caba9-9528-4aac-a9b3-9a7a56650086\",\"type\":\"BoxAnnotation\"},{\"attributes\":{},\"id\":\"296697bf-af72-4cdf-96b4-56a2a898e988\",\"type\":\"PanTool\"},{\"attributes\":{\"callback\":null,\"end\":2.5,\"start\":-2.5},\"id\":\"57f933c8-bba2-4a30-8fa8-31a94b6ea7f2\",\"type\":\"Range1d\"},{\"attributes\":{},\"id\":\"5120e79d-2c86-453b-87d6-27a661844017\",\"type\":\"WheelZoomTool\"},{\"attributes\":{\"overlay\":{\"id\":\"698caba9-9528-4aac-a9b3-9a7a56650086\",\"type\":\"BoxAnnotation\"}},\"id\":\"4cdff682-43af-4b79-acac-b0b0328048f3\",\"type\":\"BoxZoomTool\"},{\"attributes\":{},\"id\":\"c7312140-9e29-46f9-85d0-9fe36461527e\",\"type\":\"SaveTool\"},{\"attributes\":{},\"id\":\"0839ab92-6831-41e8-8bd3-5b56fa308c17\",\"type\":\"ResetTool\"},{\"attributes\":{},\"id\":\"e9c4e391-6224-43ad-9240-6118eda859c4\",\"type\":\"HelpTool\"},{\"attributes\":{\"plot\":{\"id\":\"50fe396b-f3aa-42c8-8200-f7f5cf0b903f\",\"subtype\":\"Figure\",\"type\":\"Plot\"},\"ticker\":{\"id\":\"10a1a538-3a9a-4a38-9406-c53d28521b97\",\"type\":\"BasicTicker\"}},\"id\":\"7a4f6dae-e4c8-40a6-a9b3-995274e6692f\",\"type\":\"Grid\"},{\"attributes\":{},\"id\":\"1d3c5444-78aa-4f12-9126-2551c93f3629\",\"type\":\"LinearScale\"},{\"attributes\":{},\"id\":\"6d63ed0f-81fd-43dc-a795-b7a5314a7777\",\"type\":\"LinearScale\"},{\"attributes\":{\"formatter\":{\"id\":\"b831910b-e9aa-4346-9fc1-d6d6d173b0f5\",\"type\":\"BasicTickFormatter\"},\"plot\":{\"id\":\"50fe396b-f3aa-42c8-8200-f7f5cf0b903f\",\"subtype\":\"Figure\",\"type\":\"Plot\"},\"ticker\":{\"id\":\"10a1a538-3a9a-4a38-9406-c53d28521b97\",\"type\":\"BasicTicker\"}},\"id\":\"a1c83182-3bc3-4381-858f-803c347cf7b4\",\"type\":\"LinearAxis\"},{\"attributes\":{},\"id\":\"10a1a538-3a9a-4a38-9406-c53d28521b97\",\"type\":\"BasicTicker\"},{\"attributes\":{\"formatter\":{\"id\":\"5d053908-faea-4f5b-bdb2-d325361e3c30\",\"type\":\"BasicTickFormatter\"},\"plot\":{\"id\":\"50fe396b-f3aa-42c8-8200-f7f5cf0b903f\",\"subtype\":\"Figure\",\"type\":\"Plot\"},\"ticker\":{\"id\":\"0c6c683f-c0fb-4dd1-9e97-c0ebe79a9fd1\",\"type\":\"BasicTicker\"}},\"id\":\"e15a7ba8-7265-4570-9f0f-58e3c6094c63\",\"type\":\"LinearAxis\"},{\"attributes\":{},\"id\":\"0c6c683f-c0fb-4dd1-9e97-c0ebe79a9fd1\",\"type\":\"BasicTicker\"},{\"attributes\":{\"dimension\":1,\"plot\":{\"id\":\"50fe396b-f3aa-42c8-8200-f7f5cf0b903f\",\"subtype\":\"Figure\",\"type\":\"Plot\"},\"ticker\":{\"id\":\"0c6c683f-c0fb-4dd1-9e97-c0ebe79a9fd1\",\"type\":\"BasicTicker\"}},\"id\":\"e05a4ef4-5e61-40fc-b4c8-473879607903\",\"type\":\"Grid\"},{\"attributes\":{\"data_source\":{\"id\":\"e0f16080-ad75-40e4-8ce0-5c8b830430ae\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"dc1d1cea-7415-435a-8f66-7abf27505310\",\"type\":\"Circle\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"5353bb36-e344-4b2e-9bfb-e2213dec7fcb\",\"type\":\"Circle\"},\"selection_glyph\":null,\"view\":{\"id\":\"ef855f12-300c-4e04-8d72-9f119a3378e4\",\"type\":\"CDSView\"}},\"id\":\"5d377166-00b6-4192-847c-058f619d851d\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.6},\"fill_color\":{\"value\":\"firebrick\"},\"line_alpha\":{\"value\":0.6},\"line_color\":{\"value\":\"firebrick\"},\"x\":{\"field\":\"d\"},\"y\":{\"field\":\"dzs\"}},\"id\":\"dc1d1cea-7415-435a-8f66-7abf27505310\",\"type\":\"Circle\"},{\"attributes\":{},\"id\":\"23a99c4b-852c-4bf2-ac61-864e563ff37c\",\"type\":\"BasicTickFormatter\"},{\"attributes\":{\"bottom_units\":\"screen\",\"fill_alpha\":{\"value\":0.5},\"fill_color\":{\"value\":\"lightgrey\"},\"left_units\":\"screen\",\"level\":\"overlay\",\"line_alpha\":{\"value\":1.0},\"line_color\":{\"value\":\"black\"},\"line_dash\":[4,4],\"line_width\":{\"value\":2},\"plot\":null,\"render_mode\":\"css\",\"right_units\":\"screen\",\"top_units\":\"screen\"},\"id\":\"656edf3c-53f8-46a9-a1ea-a34a902b5d44\",\"type\":\"BoxAnnotation\"},{\"attributes\":{},\"id\":\"ffc8c8cc-9107-462d-961c-54e149803f67\",\"type\":\"PanTool\"},{\"attributes\":{},\"id\":\"4486856c-1021-40f6-9a14-d942abd1f640\",\"type\":\"LinearScale\"},{\"attributes\":{\"plot\":null,\"text\":\"\"},\"id\":\"7aa5d612-daf9-4dd1-a784-d65f1756e6d2\",\"type\":\"Title\"},{\"attributes\":{},\"id\":\"e0e32655-b3e4-4d32-b267-b7e6b36aabef\",\"type\":\"WheelZoomTool\"},{\"attributes\":{\"overlay\":{\"id\":\"656edf3c-53f8-46a9-a1ea-a34a902b5d44\",\"type\":\"BoxAnnotation\"}},\"id\":\"c44f5c85-f558-4e31-9b61-55575409a220\",\"type\":\"BoxZoomTool\"},{\"attributes\":{},\"id\":\"4cf46e1c-71c4-450f-88b6-f7aa882c2fc2\",\"type\":\"SaveTool\"},{\"attributes\":{},\"id\":\"e46c7abb-d891-40e2-a6f4-2bcd1992177f\",\"type\":\"ResetTool\"},{\"attributes\":{},\"id\":\"9425dd91-7c71-43ed-8573-d60ff4963916\",\"type\":\"HelpTool\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"size\":{\"units\":\"screen\",\"value\":5},\"x\":{\"field\":\"x0\"},\"y\":{\"field\":\"x1\"}},\"id\":\"d676ac57-1d3f-448f-ba02-38042005d92d\",\"type\":\"Circle\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.6},\"fill_color\":{\"value\":\"navy\"},\"line_alpha\":{\"value\":0.6},\"line_color\":{\"value\":\"navy\"},\"size\":{\"units\":\"screen\",\"value\":5},\"x\":{\"field\":\"x0\"},\"y\":{\"field\":\"x1\"}},\"id\":\"47d1c3fb-8cfa-49be-acb9-c9cf904f7cab\",\"type\":\"Circle\"}],\"root_ids\":[\"d7710cfe-79b6-4baa-9365-7cbf833dd3b2\"]},\"title\":\"Bokeh Application\",\"version\":\"0.13.0\"}};\n",
       "  var render_items = [{\"docid\":\"9688e211-cf17-4914-8972-030fd03f0983\",\"roots\":{\"d7710cfe-79b6-4baa-9365-7cbf833dd3b2\":\"3f0d4388-a153-4321-8137-0e704d4f663f\"}}];\n",
       "  root.Bokeh.embed.embed_items_notebook(docs_json, render_items);\n",
       "\n",
       "  }\n",
       "  if (root.Bokeh !== undefined) {\n",
       "    embed_document(root);\n",
       "  } else {\n",
       "    var attempts = 0;\n",
       "    var timer = setInterval(function(root) {\n",
       "      if (root.Bokeh !== undefined) {\n",
       "        embed_document(root);\n",
       "        clearInterval(timer);\n",
       "      }\n",
       "      attempts++;\n",
       "      if (attempts > 100) {\n",
       "        console.log(\"Bokeh: ERROR: Unable to run BokehJS code because BokehJS library is missing\")\n",
       "        clearInterval(timer);\n",
       "      }\n",
       "    }, 10, root)\n",
       "  }\n",
       "})(window);"
      ],
      "application/vnd.bokehjs_exec.v0+json": ""
     },
     "metadata": {
      "application/vnd.bokehjs_exec.v0+json": {
       "id": "d7710cfe-79b6-4baa-9365-7cbf833dd3b2"
      }
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "# bokeh plot\n",
    "\n",
    "# pre-populate data source object\n",
    "z0 = np.nan*np.zeros(len(X))\n",
    "z1 = np.nan*np.zeros(len(X))\n",
    "x0s = [np.array(np.nan*np.zeros(2)) for i in range(0,len(X))]\n",
    "x1s = [np.array(np.nan*np.zeros(2)) for i in range(0,len(X))]\n",
    "d = np.nan*np.zeros(len(X))\n",
    "dzs = np.zeros(len(X))\n",
    "\n",
    "# data source\n",
    "source_data = ColumnDataSource(data=dict(x0=X[:,0], x1=X[:,1], z0=z0, z1=z1, x0s=x0s, x1s=x1s, d=d, dzs=dzs))\n",
    "\n",
    "# main plot\n",
    "plot = figure(x_range=(-3, 2.5), y_range=(-2.5, 2.5), plot_width=600, plot_height=600, match_aspect=True)\n",
    "\n",
    "# plot the new components in the mini-plot on the right\n",
    "var_plot = figure(x_range=(-3, 3), y_range=(-2.5, 2.5), plot_width = 300, plot_height = 300)\n",
    "var_plot.scatter('d', 'dzs', source=source_data, color='firebrick', alpha=0.6)\n",
    "\n",
    "# plot the data\n",
    "plot.scatter('x0', 'x1', source=source_data, color='navy', alpha=0.6, size=5)\n",
    "\n",
    "# plot the new axis\n",
    "plot.line('z0', 'z1', source=source_data, color='black', alpha=0.5)\n",
    "\n",
    "# plot the projections of the data onto the rotating line\n",
    "plot.scatter('z0', 'z1', source=source_data, color='firebrick', alpha=0.6)\n",
    "\n",
    "# plot all the lines connecting the data dots to the projection dots\n",
    "glyph = MultiLine(xs = \"x0s\", ys = \"x1s\", line_color=\"#8073ac\", line_width=1)\n",
    "plot.add_glyph(source_data, glyph)\n",
    "\n",
    "# the javascript code that calculates all the projection dots depending upon the user-chosen angle for the line to project onto\n",
    "callback = CustomJS(args=dict(source=source_data), code=\"\"\"\n",
    "    var data = source.data;\n",
    "    var x0 = data['x0']\n",
    "    var x1 = data['x1']\n",
    "    \n",
    "    var d = data['d']\n",
    "    \n",
    "    var z0 = data['z0']\n",
    "    var z1 = data['z1']\n",
    "    \n",
    "    var x0s = data['x0s']\n",
    "    var x1s = data['x1s']\n",
    "    \n",
    "    var A = ang.value*Math.PI/180;\n",
    "\n",
    "    var w = [Math.cos(A), Math.sin(A)];\n",
    "\n",
    "    for (var i = 0; i < x0.length; i++) {\n",
    "        d[i] = x0[i]*w[0] + x1[i]*w[1];\n",
    "        z0[i] = w[0]*d[i];\n",
    "        z1[i] = w[1]*d[i];\n",
    "        x0s[i] = [x0[i], z0[i]];\n",
    "        x1s[i] = [x1[i], z1[i]];\n",
    "    }\n",
    "\n",
    "    data['z0'] = z0\n",
    "    data['z1'] = z1\n",
    "    data['x0s'] = x0s\n",
    "    data['x1s'] = x1s\n",
    "    data['d'] = d\n",
    "    \n",
    "    source.change.emit();\n",
    "\"\"\")\n",
    "\n",
    "# make the slider bar\n",
    "ang_slider = Slider(start=0, end=360, value=1, step=.1, title=\"Angle\", callback=callback)\n",
    "callback.args[\"ang\"] = ang_slider\n",
    "\n",
    "# add output text\n",
    "div = Div(text=\"Instructions: There's a lot of code in the cell above! What just happened? The blue dots are our original data points. We are choosing the direction of the first PC for this dataset; this direction is represented by the black line. The red dots are the projections of the data onto the new basis direction. Using the slider bar, change the angle of the new basis direction, and observe how the projections and the variance of the projections, represented by the spread of the points in the plot on the right, change.\", width=900, height=100)\n",
    "\n",
    "# empty space div\n",
    "space_div_1 = Div(width=200, height=80)\n",
    "space_div_2 = Div(width=200, height=95)\n",
    "\n",
    "# plot layout\n",
    "lo = layout([\n",
    "  [[widgetbox(div), plot], [widgetbox(space_div_1), widgetbox(ang_slider), widgetbox(space_div_2), var_plot]],\n",
    "])\n",
    "\n",
    "# display\n",
    "show(lo)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Quiz\n",
    "Once you've played around with the interactive plot above, submit the following quiz. Based on what you've learned in the lessons about what PCA does, eyeball the plot above and choose the approximate direction of the first principal component for the above dataset. Submit your answer as an angle in degrees. Here, we are just looking for an approximate value, so we are not looking for a calculation of the correct angle, just an approximation. It will be scored correct if it's right to within ±20°."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 63,
   "metadata": {},
   "outputs": [
    {
     "ename": "ModuleNotFoundError",
     "evalue": "No module named 'quiz_tests'",
     "output_type": "error",
     "traceback": [
      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[0;31mModuleNotFoundError\u001b[0m                       Traceback (most recent call last)",
      "\u001b[0;32m<ipython-input-63-870c87af4463>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0;32mimport\u001b[0m \u001b[0mquiz_tests\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m      2\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m      3\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m      4\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mdirection_of_first_PC\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m      5\u001b[0m     \"\"\"Returns the approximate direction of the first PC as an angle in degrees.\n",
      "\u001b[0;31mModuleNotFoundError\u001b[0m: No module named 'quiz_tests'"
     ]
    }
   ],
   "source": [
    "import quiz_tests\n",
    "\n",
    "\n",
    "def direction_of_first_PC():\n",
    "    \"\"\"Returns the approximate direction of the first PC as an angle in degrees.\n",
    "\n",
    "    Returns\n",
    "    -------\n",
    "    close : int\n",
    "        The approximate angle measure of the direction of the first PC.\n",
    "    \"\"\"\n",
    "    \n",
    "    # TODO: Implement Function\n",
    "    return 21\n",
    "\n",
    "\n",
    "quiz_tests.test_direction_of_first_PC(direction_of_first_PC)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
